package com.futvan.z.framework.core;

import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.core.MethodParameter;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.futvan.z.framework.common.bean.Result;
import com.futvan.z.system.zorg.z_org;
import com.futvan.z.system.zuser.z_user;
import com.futvan.z.framework.util.DateUtil;
import com.futvan.z.framework.util.JsonUtil;
import com.futvan.z.framework.util.SystemUtil;
import com.futvan.z.system.zlog.z_log;

public class AllHandlerInterceptor extends SuperZ implements HandlerInterceptor {

	private static final ThreadLocal<Long> startTimeThreadLocal =  new NamedThreadLocal<Long>("ThreadLocal StartTime");  
	/** 
	 * Handler执行之前调用这个方法 (1)
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
		//设置请求开始时间，供afterCompletion方法计算请求周期总耗时
		startTimeThreadLocal.set(System.currentTimeMillis());
		//获取请求方法所有包路径，并判读是否验证登陆状态
		if(handler instanceof HandlerMethod) {
			HandlerMethod method= ((HandlerMethod)handler);
			String pageage = method.getBeanType().getTypeName();
			if(pageage.indexOf("com.futvan.z.framework")>=0 || pageage.indexOf("com.futvan.z.system")>=0) {
				//String methodName = method.getMethod().getName();//获取方法名
				//z.Log( methodName+" | 参数："+JsonUtil.getJson(request.getParameterMap()));
				String methodName = request.getServletPath();//获取请求URL中的方法名
				if("/login".equals(methodName) 
						|| "/error_404".equals(methodName) //404
						|| "/send_vcode".equals(methodName) //发送短信验证码
						|| "/httpservices".equals(methodName) //HTTP接口
						|| "/upload".equals(methodName) //文件上传
						|| "/deleteServerFile".equals(methodName) //删除服务器文件
						|| "/getUserOrgForUserId".equals(methodName) //根据用户ID获取登录组织列表
						|| "/getMenuList1ForWX".equals(methodName) //微信小程序中获取菜单列表1
						|| "/LoadParameter".equals(methodName) 
						|| "/default_index".equals(methodName) 
						|| "/acc_add".equals(methodName) //进账
						|| "/acc_sub".equals(methodName) //出账
						|| "/acc_unfrozen".equals(methodName) //解除冻结
						|| "/acc_remove".equals(methodName) //删除明细账
						|| methodName.indexOf("/zservices")>=0 //Z平台通用接口
						|| "/customerLogin".equals(methodName) //客户登录
						|| "/UserLogin".equals(methodName) //用户登录
						|| "/wx".equals(methodName) //微信通信接口
						|| "/UserLoginJson".equals(methodName)) {
					//当前方法不需要判读登陆状态
					return true;
				}else {
					//判读是否登陆
					if(z.isNotNull(GetSessionUserId(request))) {
						//刷新当前Session中的用户列表
						RefreshSessionUser(request);
						return true;
					}else {
						response.sendRedirect("login");
						return false;
					}
				}
			}else {
				return true;
			}
		}else {
			return true;
		}
	}

	/**
	 * Handler执行之后，ModelAndView返回之前调用这个方法 (2)
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
		if(handler instanceof HandlerMethod) {
			long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量（开始时间）    
			long endTime = System.currentTimeMillis();  //2、结束时间    
			if(handler instanceof HandlerMethod) {
				if("true".equals(z.sp.get("isPrintLog"))) {
					
					HandlerMethod method= (HandlerMethod)handler;
					BigDecimal times = (new BigDecimal(endTime).subtract(new BigDecimal(beginTime))).divide(new BigDecimal(1000),4, BigDecimal.ROUND_DOWN);
					//日志标题
					String log_title = CreateLogtitle(request,method);
					//String loginfo = "[耗时:"+times+"秒]"+method.getMethod().getName();
					String loginfo = "[耗时:"+times+"秒]"+log_title;
					//获取参数
					if(z.isNotNull(request) && request.getParameterMap().size()>0) {
						loginfo = loginfo + "[参数:"+JsonUtil.getJson(request.getParameterMap())+"]";;
					}
					z.Log(loginfo);
					
					//保存日志到数据库
					if("true".equals(z.sp.get("isInterceptorLog"))) {
						HttpSession session = null;
						try {
							session = request.getSession();
						} catch (Exception e) {}
						if(z.isNotNull(session)){
							z_log log = new z_log();
							log.setLogtype("http_log");
							log.setSessionid(session.getId());
							Object org_obj = session.getAttribute("zorg");
							z_org org = null;
							if(org_obj!=null && org_obj instanceof z_org) {
								org = (z_org) org_obj;
								log.setUserorgid(org.getZid());
							}
							Object user_obj = session.getAttribute("zuser");
							z_user user = null;
							if(user_obj!=null && user_obj instanceof z_user) {
								user = (z_user) user_obj;
								log.setUserid(user.getZid());
							}
							log.setTitle(log_title);
							log.setLoginfo(loginfo);
							log.setCustomIP(request.getRemoteAddr());
							log.setServerIP(request.getLocalAddr());
							log.setPackagepath(method.getBeanType().getTypeName());
							log.setFunctionname(method.getMethod().getName());
							log.setParameter(JSONObject.toJSONString(request.getParameterMap()));
							log.setRuntime(times.toString());
							SaveSystemLog(log);
						}
						
					}
					
				}

			}

			
		}
	}

	

	/** 
	 * Handler执行完成之后调用这个方法 (3)
	 */ 
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {

	}

}
